/*
 * Copyright (C) 2005-2006 Micronas USA Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and the associated README documentation file (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct tv_chan {
	char *name;
	int freq;
};

static struct tv_chan ntsc_bcast_table[] = {
	{ "2", 16.*55.25 },
	{ "3", 16.*61.25 },
	{ "4", 16.*67.25 },
	{ "5", 16.*77.25 },
	{ "6", 16.*83.25 },
	{ "7", 16.*175.25 },
	{ "8", 16.*181.25 },
	{ "9", 16.*187.25 },
	{ "10", 16.*193.25 },
	{ "11", 16.*199.25 },
	{ "12", 16.*205.25 },
	{ "13", 16.*211.25 },
	{ "14", 16.*471.25 },
	{ "15", 16.*477.25 },
	{ "16", 16.*483.25 },
	{ "17", 16.*489.25 },
	{ "18", 16.*495.25 },
	{ "19", 16.*501.25 },
	{ "20", 16.*507.25 },
	{ "21", 16.*513.25 },
	{ "22", 16.*519.25 },
	{ "23", 16.*525.25 },
	{ "24", 16.*531.25 },
	{ "25", 16.*537.25 },
	{ "26", 16.*543.25 },
	{ "27", 16.*549.25 },
	{ "28", 16.*555.25 },
	{ "29", 16.*561.25 },
	{ "30", 16.*567.25 },
	{ "31", 16.*573.25 },
	{ "32", 16.*579.25 },
	{ "33", 16.*585.25 },
	{ "34", 16.*591.25 },
	{ "35", 16.*597.25 },
	{ "36", 16.*603.25 },
	{ "37", 16.*609.25 },
	{ "38", 16.*615.25 },
	{ "39", 16.*621.25 },
	{ "40", 16.*627.25 },
	{ "41", 16.*633.25 },
	{ "42", 16.*639.25 },
	{ "43", 16.*645.25 },
	{ "44", 16.*651.25 },
	{ "45", 16.*657.25 },
	{ "46", 16.*663.25 },
	{ "47", 16.*669.25 },
	{ "48", 16.*675.25 },
	{ "49", 16.*681.25 },
	{ "50", 16.*687.25 },
	{ "51", 16.*693.25 },
	{ "52", 16.*699.25 },
	{ "53", 16.*705.25 },
	{ "54", 16.*711.25 },
	{ "55", 16.*717.25 },
	{ "56", 16.*723.25 },
	{ "57", 16.*729.25 },
	{ "58", 16.*735.25 },
	{ "59", 16.*741.25 },
	{ "60", 16.*747.25 },
	{ "61", 16.*753.25 },
	{ "62", 16.*759.25 },
	{ "63", 16.*765.25 },
	{ "64", 16.*771.25 },
	{ "65", 16.*777.25 },
	{ "66", 16.*783.25 },
	{ "67", 16.*789.25 },
	{ "68", 16.*795.25 },
	{ "69", 16.*801.25 },
	{ NULL, -1 },
};

static struct tv_chan ntsc_cable_table[] = {
	{ "1", 16.*73.25 },
	{ "2", 16.*55.25 },
	{ "3", 16.*61.25 },
	{ "4", 16.*67.25 },
	{ "5", 16.*77.25 },
	{ "6", 16.*83.25 },
	{ "7", 16.*175.25 },
	{ "8", 16.*181.25 },
	{ "9", 16.*187.25 },
	{ "10", 16.*193.25 },
	{ "11", 16.*199.25 },
	{ "12", 16.*205.25 },
	{ "13", 16.*211.25 },
	{ "14", 16.*121.25 },
	{ "15", 16.*127.25 },
	{ "16", 16.*133.25 },
	{ "17", 16.*139.25 },
	{ "18", 16.*145.25 },
	{ "19", 16.*151.25 },
	{ "20", 16.*157.25 },
	{ "21", 16.*163.25 },
	{ "22", 16.*169.25 },
	{ "23", 16.*217.25 },
	{ "24", 16.*223.25 },
	{ "25", 16.*229.25 },
	{ "26", 16.*235.25 },
	{ "27", 16.*241.25 },
	{ "28", 16.*247.25 },
	{ "29", 16.*253.25 },
	{ "30", 16.*259.25 },
	{ "31", 16.*265.25 },
	{ "32", 16.*271.25 },
	{ "33", 16.*277.25 },
	{ "34", 16.*283.25 },
	{ "35", 16.*289.25 },
	{ "36", 16.*295.25 },
	{ "37", 16.*301.25 },
	{ "38", 16.*307.25 },
	{ "39", 16.*313.25 },
	{ "40", 16.*319.25 },
	{ "41", 16.*325.25 },
	{ "42", 16.*331.25 },
	{ "43", 16.*337.25 },
	{ "44", 16.*343.25 },
	{ "45", 16.*349.25 },
	{ "46", 16.*355.25 },
	{ "47", 16.*361.25 },
	{ "48", 16.*367.25 },
	{ "49", 16.*373.25 },
	{ "50", 16.*379.25 },
	{ "51", 16.*385.25 },
	{ "52", 16.*391.25 },
	{ "53", 16.*397.25 },
	{ "54", 16.*403.25 },
	{ "55", 16.*409.25 },
	{ "56", 16.*415.25 },
	{ "57", 16.*421.25 },
	{ "58", 16.*427.25 },
	{ "59", 16.*433.25 },
	{ "60", 16.*439.25 },
	{ "61", 16.*445.25 },
	{ "62", 16.*451.25 },
	{ "63", 16.*457.25 },
	{ "64", 16.*463.25 },
	{ "65", 16.*469.25 },
	{ "66", 16.*475.25 },
	{ "67", 16.*481.25 },
	{ "68", 16.*487.25 },
	{ "69", 16.*493.25 },
	{ "70", 16.*499.25 },
	{ "71", 16.*505.25 },
	{ "72", 16.*511.25 },
	{ "73", 16.*517.25 },
	{ "74", 16.*523.25 },
	{ "75", 16.*529.25 },
	{ "76", 16.*535.25 },
	{ "77", 16.*541.25 },
	{ "78", 16.*547.25 },
	{ "79", 16.*553.25 },
	{ "80", 16.*559.25 },
	{ "81", 16.*565.25 },
	{ "82", 16.*571.25 },
	{ "83", 16.*577.25 },
	{ "84", 16.*583.25 },
	{ "85", 16.*589.25 },
	{ "86", 16.*595.25 },
	{ "87", 16.*601.25 },
	{ "88", 16.*607.25 },
	{ "89", 16.*613.25 },
	{ "90", 16.*619.25 },
	{ "91", 16.*625.25 },
	{ "92", 16.*631.25 },
	{ "93", 16.*637.25 },
	{ "94", 16.*643.25 },
	{ "95", 16.*91.25 },
	{ "96", 16.*97.25 },
	{ "97", 16.*103.25 },
	{ "98", 16.*109.25 },
	{ "99", 16.*115.25 },
	{ "100", 16.*649.25 },
	{ "101", 16.*655.25 },
	{ "102", 16.*661.25 },
	{ "103", 16.*667.25 },
	{ "104", 16.*673.25 },
	{ "105", 16.*679.25 },
	{ "106", 16.*685.25 },
	{ "107", 16.*691.25 },
	{ "108", 16.*697.25 },
	{ "109", 16.*703.25 },
	{ "110", 16.*709.25 },
	{ "111", 16.*715.25 },
	{ "112", 16.*721.25 },
	{ "113", 16.*727.25 },
	{ "114", 16.*733.25 },
	{ "115", 16.*739.25 },
	{ "116", 16.*745.25 },
	{ "117", 16.*751.25 },
	{ "118", 16.*757.25 },
	{ "119", 16.*763.25 },
	{ "120", 16.*769.25 },
	{ "121", 16.*775.25 },
	{ "122", 16.*781.25 },
	{ "123", 16.*787.25 },
	{ "124", 16.*793.25 },
	{ "125", 16.*799.25 },
	{ NULL, -1 },
};

static struct tv_chan ntsc_cable_hrc_table[] = {
	{ "T7", 16.*7.00 },
	{ "T8", 16.*13.00 },
	{ "T9", 16.*19.00 },
	{ "T10", 16.*25.00 },
	{ "T11", 16.*31.00 },
	{ "T12", 16.*37.00 },
	{ "T13", 16.*43.00 },
	{ "T14", 16.*49.00 },
	{ "1", 16.*72.00 },
	{ "2", 16.*54.00 },
	{ "3", 16.*60.00 },
	{ "4", 16.*66.00 },
	{ "5", 16.*78.00 },
	{ "6", 16.*84.00 },
	{ "7", 16.*174.00 },
	{ "8", 16.*180.00 },
	{ "9", 16.*186.00 },
	{ "10", 16.*192.00 },
	{ "11", 16.*198.00 },
	{ "12", 16.*204.00 },
	{ "13", 16.*210.00 },
	{ "14", 16.*120.00 },
	{ "15", 16.*126.00 },
	{ "16", 16.*132.00 },
	{ "17", 16.*138.00 },
	{ "18", 16.*144.00 },
	{ "19", 16.*150.00 },
	{ "20", 16.*156.00 },
	{ "21", 16.*162.00 },
	{ "22", 16.*168.00 },
	{ "23", 16.*216.00 },
	{ "24", 16.*222.00 },
	{ "25", 16.*228.00 },
	{ "26", 16.*234.00 },
	{ "27", 16.*240.00 },
	{ "28", 16.*246.00 },
	{ "29", 16.*252.00 },
	{ "30", 16.*258.00 },
	{ "31", 16.*264.00 },
	{ "32", 16.*270.00 },
	{ "33", 16.*276.00 },
	{ "34", 16.*282.00 },
	{ "35", 16.*288.00 },
	{ "36", 16.*294.00 },
	{ "37", 16.*300.00 },
	{ "38", 16.*306.00 },
	{ "39", 16.*312.00 },
	{ "40", 16.*318.00 },
	{ "41", 16.*324.00 },
	{ "42", 16.*330.00 },
	{ "43", 16.*336.00 },
	{ "44", 16.*342.00 },
	{ "45", 16.*348.00 },
	{ "46", 16.*354.00 },
	{ "47", 16.*360.00 },
	{ "48", 16.*366.00 },
	{ "49", 16.*372.00 },
	{ "50", 16.*378.00 },
	{ "51", 16.*384.00 },
	{ "52", 16.*390.00 },
	{ "53", 16.*396.00 },
	{ "54", 16.*402.00 },
	{ "55", 16.*408.00 },
	{ "56", 16.*414.00 },
	{ "57", 16.*420.00 },
	{ "58", 16.*426.00 },
	{ "59", 16.*432.00 },
	{ "60", 16.*438.00 },
	{ "61", 16.*444.00 },
	{ "62", 16.*450.00 },
	{ "63", 16.*456.00 },
	{ "64", 16.*462.00 },
	{ "65", 16.*468.00 },
	{ "66", 16.*474.00 },
	{ "67", 16.*480.00 },
	{ "68", 16.*486.00 },
	{ "69", 16.*492.00 },
	{ "70", 16.*498.00 },
	{ "71", 16.*504.00 },
	{ "72", 16.*510.00 },
	{ "73", 16.*516.00 },
	{ "74", 16.*522.00 },
	{ "75", 16.*528.00 },
	{ "76", 16.*534.00 },
	{ "77", 16.*540.00 },
	{ "78", 16.*546.00 },
	{ "79", 16.*552.00 },
	{ "80", 16.*558.00 },
	{ "81", 16.*564.00 },
	{ "82", 16.*570.00 },
	{ "83", 16.*576.00 },
	{ "84", 16.*582.00 },
	{ "85", 16.*588.00 },
	{ "86", 16.*594.00 },
	{ "87", 16.*600.00 },
	{ "88", 16.*606.00 },
	{ "89", 16.*612.00 },
	{ "90", 16.*618.00 },
	{ "91", 16.*624.00 },
	{ "92", 16.*630.00 },
	{ "93", 16.*636.00 },
	{ "94", 16.*642.00 },
	{ "95", 16.*90.00 },
	{ "96", 16.*96.00 },
	{ "97", 16.*102.00 },
	{ "98", 16.*108.00 },
	{ "99", 16.*114.00 },
	{ "100", 16.*648.00 },
	{ "101", 16.*654.00 },
	{ "102", 16.*660.00 },
	{ "103", 16.*666.00 },
	{ "104", 16.*672.00 },
	{ "105", 16.*678.00 },
	{ "106", 16.*684.00 },
	{ "107", 16.*690.00 },
	{ "108", 16.*696.00 },
	{ "109", 16.*702.00 },
	{ "110", 16.*708.00 },
	{ "111", 16.*714.00 },
	{ "112", 16.*720.00 },
	{ "113", 16.*726.00 },
	{ "114", 16.*732.00 },
	{ "115", 16.*738.00 },
	{ "116", 16.*744.00 },
	{ "117", 16.*750.00 },
	{ "118", 16.*756.00 },
	{ "119", 16.*762.00 },
	{ "120", 16.*768.00 },
	{ "121", 16.*774.00 },
	{ "122", 16.*780.00 },
	{ "123", 16.*786.00 },
	{ "124", 16.*792.00 },
	{ "125", 16.*798.00 },
	{ NULL, -1 },
};

static struct tv_chan ntsc_bcast_jp_table[] = {
	{ "1", 16.*91.25 },
	{ "2", 16.*97.25 },
	{ "3", 16.*103.25 },
	{ "4", 16.*171.25 },
	{ "5", 16.*177.25 },
	{ "6", 16.*183.25 },
	{ "7", 16.*189.25 },
	{ "8", 16.*193.25 },
	{ "9", 16.*199.25 },
	{ "10", 16.*205.25 },
	{ "11", 16.*211.25 },
	{ "12", 16.*217.25 },
	{ "13", 16.*471.25 },
	{ "14", 16.*477.25 },
	{ "15", 16.*483.25 },
	{ "16", 16.*489.25 },
	{ "17", 16.*495.25 },
	{ "18", 16.*501.25 },
	{ "19", 16.*507.25 },
	{ "20", 16.*513.25 },
	{ "21", 16.*519.25 },
	{ "22", 16.*525.25 },
	{ "23", 16.*531.25 },
	{ "24", 16.*537.25 },
	{ "25", 16.*543.25 },
	{ "26", 16.*549.25 },
	{ "27", 16.*555.25 },
	{ "28", 16.*561.25 },
	{ "29", 16.*567.25 },
	{ "30", 16.*573.25 },
	{ "31", 16.*579.25 },
	{ "32", 16.*585.25 },
	{ "33", 16.*591.25 },
	{ "34", 16.*597.25 },
	{ "35", 16.*603.25 },
	{ "36", 16.*609.25 },
	{ "37", 16.*615.25 },
	{ "38", 16.*621.25 },
	{ "39", 16.*627.25 },
	{ "40", 16.*633.25 },
	{ "41", 16.*639.25 },
	{ "42", 16.*645.25 },
	{ "43", 16.*651.25 },
	{ "44", 16.*657.25 },
	{ "45", 16.*663.25 },
	{ "46", 16.*669.25 },
	{ "47", 16.*675.25 },
	{ "48", 16.*681.25 },
	{ "49", 16.*687.25 },
	{ "50", 16.*693.25 },
	{ "51", 16.*699.25 },
	{ "52", 16.*705.25 },
	{ "53", 16.*711.25 },
	{ "54", 16.*717.25 },
	{ "55", 16.*723.25 },
	{ "56", 16.*729.25 },
	{ "57", 16.*735.25 },
	{ "58", 16.*741.25 },
	{ "59", 16.*747.25 },
	{ "60", 16.*753.25 },
	{ "61", 16.*759.25 },
	{ "62", 16.*765.25 },
	{ NULL, -1 },
};

static struct tv_chan ntsc_cable_jp_table[] = {
	{ "13", 16.*109.25 },
	{ "14", 16.*115.25 },
	{ "15", 16.*121.25 },
	{ "16", 16.*127.25 },
	{ "17", 16.*133.25 },
	{ "18", 16.*139.25 },
	{ "19", 16.*145.25 },
	{ "20", 16.*151.25 },
	{ "21", 16.*157.25 },
	{ "22", 16.*165.25 },
	{ "23", 16.*223.25 },
	{ "24", 16.*231.25 },
	{ "25", 16.*237.25 },
	{ "26", 16.*243.25 },
	{ "27", 16.*249.25 },
	{ "28", 16.*253.25 },
	{ "29", 16.*259.25 },
	{ "30", 16.*265.25 },
	{ "31", 16.*271.25 },
	{ "32", 16.*277.25 },
	{ "33", 16.*283.25 },
	{ "34", 16.*239.25 },
	{ "35", 16.*295.25 },
	{ "36", 16.*301.25 },
	{ "37", 16.*307.25 },
	{ "38", 16.*313.25 },
	{ "39", 16.*319.25 },
	{ "40", 16.*325.25 },
	{ "41", 16.*331.25 },
	{ "42", 16.*337.25 },
	{ "43", 16.*343.25 },
	{ "44", 16.*349.25 },
	{ "45", 16.*355.25 },
	{ "46", 16.*361.25 },
	{ "47", 16.*367.25 },
	{ "48", 16.*373.25 },
	{ "49", 16.*379.25 },
	{ "50", 16.*385.25 },
	{ "51", 16.*391.25 },
	{ "52", 16.*397.25 },
	{ "53", 16.*403.25 },
	{ "54", 16.*409.25 },
	{ "55", 16.*415.25 },
	{ "56", 16.*421.25 },
	{ "57", 16.*427.25 },
	{ "58", 16.*433.25 },
	{ "59", 16.*439.25 },
	{ "60", 16.*445.25 },
	{ "61", 16.*451.25 },
	{ "62", 16.*457.25 },
	{ "63", 16.*463.25 },
	{ NULL, -1 },
};

static struct tv_chan ccir_i_iii_table[] = {
	{ "E2", 16.*48.25 },
	{ "E3", 16.*55.25 },
	{ "E4", 16.*62.25 },
	{ "S01", 16.*69.25 },
	{ "S1", 16.*69.25 },
	{ "S02", 16.*76.25 },
	{ "S2", 16.*76.25 },
	{ "S03", 16.*83.25 },
	{ "S3", 16.*83.25 },
	{ "E5", 16.*175.25 },
	{ "E6", 16.*182.25 },
	{ "E7", 16.*189.25 },
	{ "E8", 16.*196.25 },
	{ "E9", 16.*203.25 },
	{ "E10", 16.*210.25 },
	{ "E11", 16.*217.25 },
	{ "E12", 16.*224.25 },
	{ NULL, -1 },
};

static struct tv_chan oirt_i_iii_table[] = {
	{ "R1", 16.*49.75 },
	{ "R2", 16.*59.25 },
	{ "R3", 16.*77.25 },
	{ "R4", 16.*85.25 },
	{ "R5", 16.*93.25 },
	{ "R6", 16.*175.25 },
	{ "R7", 16.*183.25 },
	{ "R8", 16.*191.25 },
	{ "R9", 16.*199.25 },
	{ "R10", 16.*207.25 },
	{ "R11", 16.*215.25 },
	{ "R12", 16.*223.25 },
	{ NULL, -1 },
};

static struct tv_chan ccir_sl_sh_table[] = {
	{ "SE1", 16.*105.25 },
	{ "SE2", 16.*112.25 },
	{ "SE3", 16.*119.25 },
	{ "SE4", 16.*126.25 },
	{ "SE5", 16.*133.25 },
	{ "SE6", 16.*140.25 },
	{ "SE7", 16.*147.25 },
	{ "SE8", 16.*154.25 },
	{ "SE9", 16.*161.25 },
	{ "SE10", 16.*168.25 },
	{ "SE11", 16.*231.25 },
	{ "SE12", 16.*238.25 },
	{ "SE13", 16.*245.25 },
	{ "SE14", 16.*252.25 },
	{ "SE15", 16.*259.25 },
	{ "SE16", 16.*266.25 },
	{ "SE17", 16.*273.25 },
	{ "SE18", 16.*280.25 },
	{ "SE19", 16.*287.25 },
	{ "SE20", 16.*294.25 },
	{ NULL, -1 },
};

static struct tv_chan oirt_sl_sh_table[] = {
	{ "SR1", 16.*111.25 },
	{ "SR2", 16.*119.25 },
	{ "SR3", 16.*127.25 },
	{ "SR4", 16.*135.25 },
	{ "SR5", 16.*143.25 },
	{ "SR6", 16.*151.25 },
	{ "SR7", 16.*159.25 },
	{ "SR8", 16.*167.25 },
	{ "SR11", 16.*231.25 },
	{ "SR12", 16.*239.25 },
	{ "SR13", 16.*247.25 },
	{ "SR14", 16.*255.25 },
	{ "SR15", 16.*263.25 },
	{ "SR16", 16.*271.25 },
	{ "SR17", 16.*279.25 },
	{ "SR18", 16.*287.25 },
	{ NULL, -1 },
};

static struct tv_chan ccir_h_table[] = {
	{ "S21", 16.*303.25 },
	{ "S22", 16.*311.25 },
	{ "S23", 16.*319.25 },
	{ "S24", 16.*327.25 },
	{ "S25", 16.*335.25 },
	{ "S26", 16.*343.25 },
	{ "S27", 16.*351.25 },
	{ "S28", 16.*359.25 },
	{ "S29", 16.*367.25 },
	{ "S30", 16.*375.25 },
	{ "S31", 16.*383.25 },
	{ "S32", 16.*391.25 },
	{ "S33", 16.*399.25 },
	{ "S34", 16.*407.25 },
	{ "S35", 16.*415.25 },
	{ "S36", 16.*423.25 },
	{ "S37", 16.*431.25 },
	{ "S38", 16.*439.25 },
	{ "S39", 16.*447.25 },
	{ "S40", 16.*455.25 },
	{ "S41", 16.*465.25 },
	{ NULL, -1 },
};

static struct tv_chan oirt_h_table[] = {
	{ "S19", 16.*295.25 },
	{ "S20", 16.*303.25 },
	{ "S21", 16.*311.25 },
	{ "S22", 16.*319.25 },
	{ "S23", 16.*327.25 },
	{ "S24", 16.*335.25 },
	{ "S25", 16.*343.25 },
	{ "S26", 16.*351.25 },
	{ "S27", 16.*359.25 },
	{ "S28", 16.*367.25 },
	{ "S29", 16.*375.25 },
	{ "S30", 16.*383.25 },
	{ "S31", 16.*391.25 },
	{ "S32", 16.*399.25 },
	{ "S33", 16.*407.25 },
	{ "S34", 16.*415.25 },
	{ "S35", 16.*423.25 },
	{ "S36", 16.*431.25 },
	{ "S37", 16.*439.25 },
	{ "S38", 16.*447.25 },
	{ "S39", 16.*455.25 },
	{ "S40", 16.*463.25 },
	{ NULL, -1 },
};

static struct tv_chan pal_ireland_table[] = {
	{ "A0", 16.*45.75 },
	{ "A1", 16.*48.00 },
	{ "A2", 16.*53.75 },
	{ "A3", 16.*56.00 },
	{ "A4", 16.*61.75 },
	{ "A5", 16.*64.00 },
	{ "A6", 16.*175.25 },
	{ "A7", 16.*176.00 },
	{ "A8", 16.*183.25 },
	{ "A9", 16.*184.00 },
	{ "A10", 16.*191.25 },
	{ "A11", 16.*192.00 },
	{ "A12", 16.*199.25 },
	{ "A13", 16.*200.00 },
	{ "A14", 16.*207.25 },
	{ "A15", 16.*208.00 },
	{ "A16", 16.*215.25 },
	{ "A17", 16.*216.00 },
	{ "A18", 16.*224.00 },
	{ "A19", 16.*232.00 },
	{ "A20", 16.*248.00 },
	{ "A21", 16.*256.00 },
	{ "A22", 16.*264.00 },
	{ "A23", 16.*272.00 },
	{ "A24", 16.*280.00 },
	{ "A25", 16.*288.00 },
	{ "A26", 16.*296.00 },
	{ "A27", 16.*304.00 },
	{ "A28", 16.*312.00 },
	{ "A29", 16.*320.00 },
	{ "A30", 16.*344.00 },
	{ "A31", 16.*352.00 },
	{ "A32", 16.*408.00 },
	{ "A33", 16.*415.00 },
	{ "A34", 16.*448.00 },
	{ "A35", 16.*480.00 },
	{ "A36", 16.*520.00 },
	{ NULL, -1 },
};

static struct tv_chan pal_italy_table[] = {
	{ "A", 16.*53.75 },
	{ "B", 16.*62.25 },
	{ "C", 16.*82.25 },
	{ "D", 16.*175.25 },
	{ "E", 16.*183.75 },
	{ "F", 16.*192.25 },
	{ "G", 16.*201.25 },
	{ "H", 16.*210.25 },
	{ "H1", 16.*217.25 },
	{ "H2", 16.*224.25 },
	{ NULL, -1 },
};

static struct tv_chan secam_france_table[] = {
	{ "K01", 16.*47.75 },
	{ "K1", 16.*47.75 },
	{ "K02", 16.*55.75 },
	{ "K2", 16.*55.75 },
	{ "K03", 16.*60.50 },
	{ "K3", 16.*60.50 },
	{ "K04", 16.*63.75 },
	{ "K4", 16.*63.75 },
	{ "KB", 16.*116.75 },
	{ "KC", 16.*128.75 },
	{ "KD", 16.*140.75 },
	{ "KE", 16.*159.75 },
	{ "KF", 16.*164.75 },
	{ "K05", 16.*176.00 },
	{ "K5", 16.*176.00 },
	{ "KG", 16.*176.75 },
	{ "K06", 16.*184.00 },
	{ "K6", 16.*184.00 },
	{ "KH", 16.*188.75 },
	{ "K07", 16.*192.00 },
	{ "K7", 16.*192.00 },
	{ "K08", 16.*200.00 },
	{ "K8", 16.*200.00 },
	{ "KI", 16.*200.75 },
	{ "K09", 16.*208.00 },
	{ "K9", 16.*208.00 },
	{ "KJ", 16.*212.75 },
	{ "K10", 16.*216.00 },
	{ "KK", 16.*224.75 },
	{ "KL", 16.*236.75 },
	{ "KM", 16.*248.75 },
	{ "KN", 16.*260.75 },
	{ "KO", 16.*272.75 },
	{ "KP", 16.*284.75 },
	{ "KQ", 16.*296.75 },
	{ "H01", 16.*303.25 },
	{ "H02", 16.*311.25 },
	{ "H03", 16.*319.25 },
	{ "H04", 16.*327.25 },
	{ "H05", 16.*335.25 },
	{ "H06", 16.*343.25 },
	{ "H07", 16.*351.25 },
	{ "H08", 16.*359.25 },
	{ "H09", 16.*367.25 },
	{ "H10", 16.*375.25 },
	{ "H11", 16.*383.25 },
	{ "H12", 16.*391.25 },
	{ "H13", 16.*399.25 },
	{ "H14", 16.*407.25 },
	{ "H15", 16.*415.25 },
	{ "H16", 16.*423.25 },
	{ "H17", 16.*431.25 },
	{ "H18", 16.*439.25 },
	{ "H19", 16.*447.25 },
	{ NULL, -1 },
};

static struct tv_chan uhf_table[] = {
	{ "21", 16.*471.25 },
	{ "22", 16.*479.25 },
	{ "23", 16.*487.25 },
	{ "24", 16.*495.25 },
	{ "25", 16.*503.25 },
	{ "26", 16.*511.25 },
	{ "27", 16.*519.25 },
	{ "28", 16.*527.25 },
	{ "29", 16.*535.25 },
	{ "30", 16.*543.25 },
	{ "31", 16.*551.25 },
	{ "32", 16.*559.25 },
	{ "33", 16.*567.25 },
	{ "34", 16.*575.25 },
	{ "35", 16.*583.25 },
	{ "36", 16.*591.25 },
	{ "37", 16.*599.25 },
	{ "38", 16.*607.25 },
	{ "39", 16.*615.25 },
	{ "40", 16.*623.25 },
	{ "41", 16.*631.25 },
	{ "42", 16.*639.25 },
	{ "43", 16.*647.25 },
	{ "44", 16.*655.25 },
	{ "45", 16.*663.25 },
	{ "46", 16.*671.25 },
	{ "47", 16.*679.25 },
	{ "48", 16.*687.25 },
	{ "49", 16.*695.25 },
	{ "50", 16.*703.25 },
	{ "51", 16.*711.25 },
	{ "52", 16.*719.25 },
	{ "53", 16.*727.25 },
	{ "54", 16.*735.25 },
	{ "55", 16.*743.25 },
	{ "56", 16.*751.25 },
	{ "57", 16.*759.25 },
	{ "58", 16.*767.25 },
	{ "59", 16.*775.25 },
	{ "60", 16.*783.25 },
	{ "61", 16.*791.25 },
	{ "62", 16.*799.25 },
	{ "63", 16.*807.25 },
	{ "64", 16.*815.25 },
	{ "65", 16.*823.25 },
	{ "66", 16.*831.25 },
	{ "67", 16.*839.25 },
	{ "68", 16.*847.25 },
	{ "69", 16.*855.25 },
	{ NULL, -1 },
};

static struct {
	char *name;
	struct tv_chan *tab;
} tv_freq_list[] = {
	{ "ntsc-bcast", ntsc_bcast_table },
	{ "ntsc-cable", ntsc_cable_table },
	{ "us-bcast", ntsc_bcast_table },
	{ "us-cable", ntsc_cable_table },
	{ "ntsc-cable-hrc", ntsc_cable_hrc_table },
	{ "ntsc-hrc", ntsc_cable_hrc_table },
	{ "us-cable-hrc", ntsc_cable_hrc_table },
	{ "us-hrc", ntsc_cable_hrc_table },
	{ "ntsc-bcast-jp", ntsc_bcast_jp_table },
	{ "ntsc-cable-jp", ntsc_cable_jp_table },
	{ "japan-bcast", ntsc_bcast_jp_table },
	{ "japan-cable", ntsc_cable_jp_table },
	{ "europe-west", ccir_i_iii_table },
	{ "europe-west", ccir_sl_sh_table },
	{ "europe-west", ccir_h_table },
	{ "europe-west", uhf_table },
	{ "europe-east", oirt_i_iii_table },
	{ "europe-east", oirt_sl_sh_table },
	{ "europe-east", ccir_i_iii_table },
	{ "europe-east", ccir_sl_sh_table },
	{ "europe-east", ccir_h_table },
	{ "europe-east", uhf_table },
	{ "europe", oirt_i_iii_table },
	{ "europe", oirt_sl_sh_table },
	{ "europe", ccir_i_iii_table },
	{ "europe", ccir_sl_sh_table },
	{ "europe", ccir_h_table },
	{ "europe", pal_ireland_table },
	{ "europe", pal_italy_table },
	{ "europe", uhf_table },
	{ "pal-ireland", pal_ireland_table },
	{ "pal-ireland", uhf_table },
	{ "ireland", pal_ireland_table },
	{ "ireland", uhf_table },
	{ "pal-italy", pal_italy_table },
	{ "pal-italy", uhf_table },
	{ "italy", pal_italy_table },
	{ "italy", uhf_table },
	{ "secam-france", secam_france_table },
	{ "secam-france", uhf_table },
	{ "france", secam_france_table },
	{ "france", uhf_table },
	{ "secam-russia", ccir_i_iii_table },
	{ "secam-russia", ccir_sl_sh_table },
	{ "secam-russia", ccir_h_table },
	{ "secam-russia", uhf_table },
	{ "russia", oirt_i_iii_table },
	{ "russia", oirt_sl_sh_table },
	{ "russia", oirt_h_table },
	{ "russia", uhf_table },
	{ NULL, NULL },	/* Terminating entry */
};

/*
 * This function takes a channel name as an argument, prefixed with a
 * frequency band name as defined in the table above and a colon.  E.g.
 * "us-bcast:10".  The returned value is suitable for passing to V4L/V4L2.
 */
int chan_to_freq(char *name)
{
	char *c;
	int b, chan, freq = -1, band_exists = 0;

	c = strchr(name, ':');
	if (c == NULL) {
		fprintf(stderr, "error: channel must indicate a band name\n");
		return -1;
	}
	*c = 0;
	for (b = 0; tv_freq_list[b].name != NULL; ++b) {
		if (strcasecmp(tv_freq_list[b].name, name))
			continue;
		band_exists = 1;
		for (chan = 0; tv_freq_list[b].tab[chan].name; ++chan) {
			if (strcasecmp(tv_freq_list[b].tab[chan].name, c + 1))
				continue;
			freq = tv_freq_list[b].tab[chan].freq;
			goto done;
		}
	}
	if (band_exists)
		fprintf(stderr, "error: channel \"%s\" is not valid for "
				"frequency band \"%s\"\n", c + 1, name);
	else
		fprintf(stderr, "error: frequency band \"%s\" is unknown\n",
				name);
done:
	*c = ':';
	return freq; /* may be -1 if invalid */
}
